<?php
declare(strict_types=1);

namespace ExpressionEngine;

use ExpressionEngine\ConstantEngine\ConstantEngineInterface;
use ExpressionEngine\ExpressionEngine\Enum\ExpressionEnum;
use ExpressionEngine\ExpressionEngine\ExpressionEngineInterface;
use ExpressionEngine\LexicalAnalysisEngine\Enum\LexicalAnalysisEnum;
use ExpressionEngine\LexicalAnalysisEngine\LexicalAnalysisEngineInterface;
use ExpressionEngine\VariableEngine\VariableEngineInterface;

class ExpressionLogic
{
    protected LexicalAnalysisEngineInterface $lexicalAnalysisEngine;
    protected VariableEngineInterface $variableEngine;
    protected ConstantEngineInterface $constantEngine;
    protected ExpressionEngineInterface $expressionEngine;

    public function __construct(LexicalAnalysisEngineInterface $lexicalAnalysisEngine, VariableEngineInterface $variableEngine, ConstantEngineInterface $constantEngine, ExpressionEngineInterface $expressionEngine)
    {
        $this->lexicalAnalysisEngine = $lexicalAnalysisEngine;
        $this->variableEngine = $variableEngine;
        $this->constantEngine = $constantEngine;
        $this->expressionEngine = $expressionEngine;
    }


    public function getScanningData(string $expression): array
    {
        return $this->lexicalAnalysisEngine->scanning($expression);
    }

    public function compile(array $scanningData, array $context, array $compileContext): mixed
    {
        if (!empty($scanningData[LexicalAnalysisEnum::SCAN_KEY_VARIABLE_LIST_NAME])) {
            $compileContext[ExpressionEnum::COMPILE_ID_VARIABLE_LIST] = $this->variableEngine->compileList($scanningData[LexicalAnalysisEnum::SCAN_KEY_VARIABLE_LIST_NAME], $context);
        }
        if (!empty($scanningData[LexicalAnalysisEnum::SCAN_KEY_CONSTANT_LIST_NAME])) {
            $compileContext[ExpressionEnum::COMPILE_ID_CONSTANT_LIST] = $this->constantEngine->compileList($scanningData[LexicalAnalysisEnum::SCAN_KEY_CONSTANT_LIST_NAME]);
        }
        if (!empty($scanningData[LexicalAnalysisEnum::SCAN_KEY_EXPRESSION_LIST_NAME])) {
            $compileContext[ExpressionEnum::COMPILE_ID_EXPRESSION_LIST] = $this->expressionEngine->compileList($scanningData[LexicalAnalysisEnum::SCAN_KEY_EXPRESSION_LIST_NAME], $compileContext);
        }
        return end($compileContext[ExpressionEnum::COMPILE_ID_EXPRESSION_LIST]);
    }
}